#pragma once
#include <asio.hpp>
#include <set>
#include "as_netbase.h"
#include "noncopyobj.h"
#include "thread_pool.h"
#include "object_pool.h"
#include "byte_buffer.h"

namespace as
{
namespace net
{
class BasePacket;
class TcpServer : public as::noncopyobj
{
public:
	TcpServer(asio::io_context &io);
	virtual ~TcpServer();
	static as::net::TcpServerPtr CreateServer(asio::io_context &io, const std::string &addr, int port);
	int bind(const std::string &addr, int port);
	void SetThreadNum(int num);

	void StartAccept();

	ByteBuffer *PopByteBuffer();
	void PushByteBufffr(ByteBuffer *ptr);
	void AddConnection(TcpConnPtr &con);
	void DelConnection(TcpConnPtr &con);
	
	virtual void HandleMsg(const TcpConnPtr &con, ByteBuffer &buf);
	virtual void HandleState(const TcpConnPtr &con);
private:
	asio::ip::tcp::endpoint addr_;
	asio::ip::tcp::acceptor accp_;
	asio::io_context &io_;
	TcpCallBack statecb_, readcb_;
	MsgCallBack msgcb_;
	std::function<TcpConnPtr()> createcb_;
	BasePacket *pack_ = nullptr;
	ThreadPool thread_pool_;
	ObjectPool<ByteBuffer, std::mutex> byte_buff_pool_;
	std::atomic_bool isStart = false;
	std::set<TcpConnPtr> connections_;
};

}
}